import { useTransitionSetting } from '@/layouts/use/useTransitionSetting';
import { LINK_HOME, LINK_LOGIN, PAGE_NOT_FOUND_ROUTE, USER_WRAPPER_PAGE_LIST, WHITE_NAME_LIST } from '@/router/constants';
import { usePermissionStoreWithOut } from '@/store/modules/permission';
import { useUserStoreWithOut } from '@/store/modules/user';
import { decodeByBase64 } from '@vc/utils';
import { createPageLoadingGuard, createPermissionGuard, createProgressGuard } from 'vc/src/router';
import type { Router } from 'vue-router';
import { setRouteChange } from 'vc/src/router';
import { LINK_NEWS_INDEX } from './routes/business/news';

/**
 * @description 路由守卫
 */
export function setupRouterGuard(router: Router) {
  const userStore = useUserStoreWithOut();
  const permissionStore = usePermissionStoreWithOut();
  const hasToken = userStore.getToken;
  const { getOpenPageLoading, getOpenNProgress } = useTransitionSetting();
  const openPageLoading = unref(getOpenPageLoading);
  const openNProgress = unref(getOpenNProgress);
  
  router.beforeEach(async (to) => {
    if (to.meta.isIframe) {
      to.meta.frameSrc = decodeByBase64(to.params?.url as string);
    }
  });
  
  createPageGuard(router);
  openPageLoading && createPageLoadingGuard(router, !!hasToken, openPageLoading);
  openNProgress && createProgressGuard(router, openNProgress);
  createPermissionGuard({
    router: router,
    userStore,
    permissionStore,
    whitePathList: WHITE_NAME_LIST,
    backHomePaths: USER_WRAPPER_PAGE_LIST,
    homePath: LINK_HOME,
    loginPath: LINK_LOGIN,
    notFoundRoute: PAGE_NOT_FOUND_ROUTE
  });
}

function createPageGuard(router: Router) {
  const target = '.layout-content';
  const loadedPageMap = new Map<string, any>();
  router.beforeEach(async (to, from) => {
    const scrollContainer = document.querySelector(from.meta.scrollDom || target) as HTMLElement;
    loadedPageMap.set(from.fullPath, {
      ...loadedPageMap.get(from.fullPath),
      scrollTop: scrollContainer?.scrollTop
    });
    
    /**
     * 如果页面已经加载，再次打开会更快，不需要显示 loading 或者其他加载效果
     * loadedPageMap.get(to.path) 如果能取到值则返回 true 否则返回 false
     */
    to.meta.loaded = !!loadedPageMap.get(to.fullPath)?.loaded;
    // 调用路由变化的事件
    setRouteChange(to);
    
    return true;
  });
  
  // 将已经打开的路由的 path 存储到 loadedPageMap map 对象当中
  router.afterEach((to) => {
    nextTick(() => {
      const scrollContainer = document.querySelector(to.meta.scrollDom || target) as HTMLElement;
      if (scrollContainer && !to.meta.ignoreKeepAlive) {
        useTimeoutFn(() => {
          scrollContainer.scrollTop = loadedPageMap.get(to.fullPath).scrollTop;
        }, 0);
      }
    });
    
    loadedPageMap.set(to.fullPath, { ...loadedPageMap.get(to.fullPath), loaded: true });
  });
}
